package com.hrg.rds.biz.robot.service.impl;

import cn.hutool.core.util.IdUtil;
import com.hrg.rds.biz.comm.ConfigService;
import com.hrg.rds.biz.config.RdsConfiguration;
import com.hrg.rds.biz.robot.domain.Agv;
import com.hrg.rds.biz.robot.domain.AgvStatus;
import com.hrg.rds.biz.robot.domain.AgvVo;
import com.hrg.rds.biz.robot.mapper.AgvMapper;
import com.hrg.rds.biz.robot.service.AgvService;
import com.hrg.rds.biz.station.domain.Segment;
import com.hrg.rds.biz.station.domain.Station;
import com.hrg.rds.biz.station.mapper.SegmentMapper;
import com.hrg.rds.biz.station.mapper.StationMapper;
import com.hrg.seer.sdk.rbk.msg.config.ConfigDownloadMapRes;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Slf4j
@Service
public class AgvServiceImpl implements AgvService {

    @Autowired
    private AgvMapper agvMapper;
    @Autowired
    private StationMapper stationMapper;
    @Autowired
    private SegmentMapper segmentMapper;

    @Override
    public List<AgvVo> selectList() {
        List<Agv> agvs = agvMapper.selectList();
        List<AgvVo> agvVos = new ArrayList<>();
        for (Agv agv : agvs) {
            AgvVo agvVo = new AgvVo();
            agvVo.setId(agv.getId());
            agvVo.setName(agv.getName());
            agvVo.setCode(agv.getCode());
            agvVo.setType(agv.getType());
            agvVo.setIp(agv.getIp());
            agvVo.setPort(agv.getPort());
            agvVo.setChargeStation(agv.getChargeStationId());
            agvVo.setStandbyStation(agv.getStandbyStationId());
            agvVo.setStatus(agv.getStatus());
            agvVo.setIfEnabled(agv.isIfEnabled());
            agvVos.add(agvVo);
        }
        return agvVos;
    }

    @Override
    public boolean tryControl(String agvIp) {
        // 实现尝试控制AGV的逻辑
        log.info("尝试抢占控制权 agvIp = {} ", agvIp);
        Optional<AgvVo> first = RdsConfiguration.AgvIpMap.values().stream().filter(agvVo -> agvVo.getIp().equals(agvIp)).findFirst();
        if (first.isPresent()) {
            return ConfigService.configLock(agvIp);
        }
        return false;
    }

    @Override
    public boolean releaseControl(String agvIp) {
        // 实现释放AGV控制的逻辑
        log.info("尝试释放控制权 agvIp = {} ", agvIp);
        Optional<AgvVo> first = RdsConfiguration.AgvIpMap.values().stream().filter(agvVo -> agvVo.getIp().equals(agvIp)).findFirst();
        if (first.isPresent()) {
            return ConfigService.configUnlock(agvIp);
        }
        return false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean status(int status, String agvIp) {
        // 实现更新AGV状态的逻辑
        log.info("更新AGV状态，agvIp = {}, status = {}: ", agvIp, status);
        Optional<AgvVo> first = RdsConfiguration.AgvIpMap.values().stream().filter(agvVo -> agvVo.getIp().equals(agvIp)).findFirst();
        if (first.isPresent()) {
            String id = first.get().getId();
            Agv agv = new Agv();
            agv.setId(id);
            agv.setStatus(AgvStatus.getByCode(status));
            agvMapper.updateById(agv);
            return true;
        }
        return false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean downloadMap(String agvIp) {
        // 实现下载AGV地图的逻辑
        String mapName = "default";
        Optional<AgvVo> first = RdsConfiguration.AgvIpMap.values().stream().filter(agvVo -> agvVo.getIp().equals(agvIp)).findFirst();
        if (first.isPresent()) {
            mapName = first.get().getUsingMapName();
        }
        ConfigDownloadMapRes configDownloadMapRes = ConfigService.configDownloadMap(agvIp, mapName);
        if (configDownloadMapRes == null) {
            log.info("下载地图失败，agvIp={}, mapName = {}", agvIp, mapName);
            return false;
        }
        log.info("下载地图成功，agvIp={}, mapName = {}", agvIp, mapName);
        // 处理结果，存入数据库
        List<Station> stationList = new ArrayList<>();
        List<Segment> segmentList = new ArrayList<>();
        Date createTime = new Date();
        configDownloadMapRes.getAdvancedPointList().forEach(advancedPoint -> {
            log.info("advancedPoint:{}", advancedPoint);
            String className = advancedPoint.getClassName();
            String instanceName = advancedPoint.getInstanceName();
            ConfigDownloadMapRes.Position position = advancedPoint.getPos();
            Station station = new Station();
            station.setId(IdUtil.getSnowflakeNextIdStr());
            station.setCode(instanceName);
            station.setName(instanceName);
            station.setAxisX(position.getX());
            station.setAxisY(position.getY());
            station.setIfEnabled(true);
            //station.setCreateBy(SecurityUtils.getUsername());
            station.setCreateTime(createTime);
            if (className.equals("ActionPoint")) {
                station.setType(3);//取卸货点
            } else if (className.equals("ChargePoint")) {
                station.setType(1);//充电点
            } else {
                //if (className.equals("LocationMark")
                station.setType(0);//普通点
            }
            stationList.add(station);
        });

        configDownloadMapRes.getAdvancedCurveList().forEach(advancedCurve -> {
            log.info("advancedCurve:{}", advancedCurve);
            String className = advancedCurve.getClassName();
            String instanceName = advancedCurve.getInstanceName();
            ConfigDownloadMapRes.StartEndPosition startPos = advancedCurve.getStartPos();
            ConfigDownloadMapRes.StartEndPosition endPos = advancedCurve.getEndPos();
            Segment segment = new Segment();
            segment.setId(IdUtil.getSnowflakeNextIdStr());
            segment.setCode(instanceName);
            segment.setName(instanceName);
            segment.setStartStation(startPos.getInstanceName());
            segment.setEndStation(endPos.getInstanceName());
            // MA==正走 1，MQ==倒走 -1
            ConfigDownloadMapRes.Property property = advancedCurve.getProperty().stream().filter(o -> "direction".equals(o.getKey())).findFirst().orElse(null);
            if (property == null) {
                segment.setDirection(1);
            } else {
                segment.setDirection("MA==".equals(property.getValue()) ? 1 : -1);
            }
            segment.setLength(2);
            segment.setSpeed(0.5);
            segment.setIfStartEndAdjoining(true);
            segment.setIfEnabled(true);
            //segment.setCreateBy(SecurityUtils.getUsername());
            segment.setCreateTime(createTime);
            // StraightPath/DegenerateBezier/BezierPath
            if (className.equals("StraightPath")) {
                segment.setType(0);//直线
                segment.setAxis1X(0);
                segment.setAxis1Y(0);
                segment.setAxis2X(0);
                segment.setAxis2Y(0);
                segment.setAxis3X(0);
                segment.setAxis3Y(0);
                segment.setAxis4X(0);
                segment.setAxis4Y(0);
            } else {
                ConfigDownloadMapRes.ControlPosition controlPos1 = advancedCurve.getControlPos1();
                ConfigDownloadMapRes.ControlPosition controlPos2 = advancedCurve.getControlPos2();
                segment.setType(1);//曲线
                segment.setAxis1X(startPos.getPos().getX());
                segment.setAxis1Y(startPos.getPos().getY());
                segment.setAxis2X(controlPos1.getX());
                segment.setAxis2Y(controlPos1.getY());
                segment.setAxis3X(controlPos2.getX());
                segment.setAxis3Y(controlPos2.getY());
                segment.setAxis4X(endPos.getPos().getX());
                segment.setAxis4Y(endPos.getPos().getY());
            }
            segmentList.add(segment);
        });

       // 存储到数据库
        stationMapper.truncateTable();
        stationMapper.insertBatch(stationList);
        segmentMapper.truncateTable();
        segmentMapper.insertBatch(segmentList);
        log.info("导入地图成功，agvIp={}, mapName = {}", agvIp, mapName);
        return true;
    }

    @Override
    public boolean updateById(Agv agv) {
        agvMapper.updateById(agv);
        return false;
    }
}
